<!DOCTYPE html>
<html>

<head>
    <title>demo</title>
</head>
<style type="text/css">
    html,body{
        margin:0;
        padding: 0;
        position: relative;
    }
    #canvas{
        position: absolute;
    }
</style>
<body>
    <canvas id="canvas"></canvas>
</body>
<script type="text/javascript">
var canvas = document.getElementById('canvas');
var ctx = canvas.getContext('2d');

var Grewer = {
    init: function() {
        this.getWindowSize();
        canvas.width = this.w;
        canvas.height = this.h;
        this.num = 70;
        this.range = 100;
        this.arr = [];
        this.add();
    },
    getWindowSize: function() {
        //获取窗口宽度
        if (window.innerWidth) { //兼容火狐，谷歌,safari等浏览器
            this.w = window.innerWidth;
        } else if ((document.body) && (document.body.clientWidth)) { //兼容IE浏览器
            this.w = document.body.clientWidth;
        }

        //获取窗口高度
        if (window.innerHeight) {
            this.h = window.innerHeight;
        } else if ((document.body) && (document.body.clientHeight)) {
            this.h = document.body.clientHeight;
        }
    },
    update: function(obj) {
        obj.x += obj.vx;
        obj.y += obj.vy;

        if (obj.x < 0 || obj.x > this.w) {
            obj.vx *= -1;
        }
        if (obj.y < 0 || obj.y > this.h) {
            obj.vy *= -1;
        }
    },
    add: function() {

        var i = this.num;
        while (i--) {
            var particles = {
                x: (Math.random() * this.w) | 0,
                y: (Math.random() * this.h) | 0,
                vx: (Math.random() - .5) * 2,
                vy: (Math.random() - .5) * 2,
                r: ((Math.random() * 2) | 0) + 1,
                color:new Color()
            }
            this.arr.push(particles);
        }
    },
    checkDist: function(a, b, dist) {
        var x = a.x - b.x,
            y = a.y - b.y;

        return x * x + y * y <= dist * dist;
    },
    print: function(obj) {
        ctx.beginPath();
        ctx.arc(obj.x, obj.y, obj.r, 0, 2 * Math.PI);
        ctx.fillStyle = obj.color.style;
        ctx.fill();
    }


}
var G = Object.create(Grewer);
G.init();
var Ganim = function() {
    window.requestAnimationFrame(Ganim);

    ctx.fillStyle = '#000';
    ctx.fillRect(0, 0, G.w, G.h);

    var length = G.arr.length;
    for (var i = 0; i < length; i++) {
        var o1 = G.arr[i]
        G.update(o1);
        G.print(o1);

        for (var j = i + 1; j < length; ++j) {

            var o2 = G.arr[j];
            if (G.checkDist(o1, o2, G.range)) {
                // ctx.strokeStyle = '#cccccc';
                ctx.strokeStyle = averageColorStyles(o1, o2);
                ctx.beginPath();
                ctx.moveTo(o1.x, o1.y);
                ctx.lineTo(o2.x, o2.y);
                ctx.stroke();
            }
        }

    }
}
function colorValue(min) {
    return Math.floor(Math.random() * 255 + min);
  }
function Color(min) {
    min = min || 0;
    this.r = colorValue(min);
    this.g = colorValue(min);
    this.b = colorValue(min);
    this.style = createColorStyle(this.r, this.g, this.b);
  }
  function createColorStyle(r,g,b) {
    return 'rgba(' + r + ',' + g + ',' + b + ', 0.8)';
  }
  function mixComponents(comp1, weight1, comp2, weight2) {
    return (comp1 * weight1 + comp2 * weight2) / (weight1 + weight2);
  }
function averageColorStyles(dot1, dot2) {
    var color1 = dot1.color,
        color2 = dot2.color;
    
    var r = mixComponents(color1.r, dot1.x, color2.r, dot2.x),
        g = mixComponents(color1.g, dot1.x, color2.g, dot2.x),
        b = mixComponents(color1.b, dot1.x, color2.b, dot2.x);
    return createColorStyle(Math.floor(r), Math.floor(g), Math.floor(b));
  }
G.arr.push({
    x: 1,
    y: 1,
    vx: 0,
    vy: 0,
    r: 1,
    color:new Color()
})
document.addEventListener('mousemove', function(e) {
    G.arr[G.num].x = e.clientX - canvas.offsetLeft;
    G.arr[G.num].y = e.clientY - canvas.offsetTop;

}, false)
Ganim();
</script>

</html>